package com.yanqu.road.dataHelper.manager;

import com.yanqu.road.dao.db.DbNameStrategy;
import com.yanqu.road.entity.activity.ActivityConditionInfo;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class ActivityMgr extends BaseMgr {

    static Object lock = new Object();

    static Map<Integer, ActivityInfo> activityInfoMap = new ConcurrentHashMap<>();

    static Map<Integer,List<ActivityConditionInfo>> activityConditionInfoMap = new ConcurrentHashMap<>();


    public ActivityMgr(){

    }

    public  List<ActivityInfo> getAllRunningActivity() {
        return new ArrayList<>(activityInfoMap.values());
    }

    public List<ActivityInfo> getServerAllRunningActivity(long serverId) {
        List<ActivityInfo> runningActivityList = new ArrayList<>();
        for (ActivityInfo activityInfo : activityInfoMap.values()) {
            if (activityInfo.getServerIdList().contains(serverId)) {
                runningActivityList.add(activityInfo);
            }
        }
        return runningActivityList;
    }

    public  void initAllRunningActivity() {
        ResultSet rs = null;
        CallableStatement call = null;
        Map<Integer, ActivityInfo> dataMap = new ConcurrentHashMap<>();
        String sql = "select * from t_s_activity_main where beginShowTime <= ? AND ? <= endShowTime";
        try {
            getDb().setConnName(DbNameStrategy.getServerDb());
            call = getDb().getConnection().prepareCall(sql);
            call.setString(1,DateHelper.getCurrentDateTimeString() );
            call.setString(2,DateHelper.getCurrentDateTimeString() );
            rs = call.executeQuery();
            while (rs.next()) {
                ActivityInfo data = parseActivityInfo(rs);
                activityInfoMap.put(data.getActivityId(), data);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            getDb().closeConnection(call, rs);
        }
    }

    public void initActivity(int activityId){
        synchronized (lock){
            if(!activityInfoMap.containsKey(activityId)){
                initActivityInfo(activityId);
                initActivityConditionInfoMap(activityId);
            }
        }
    }

    public static ActivityInfo getActivityInfo(int activityId){
        return activityInfoMap.get(activityId);
    }


    public static ActivityConditionInfo getActivityConditionInfo(int activityId,int conditionId){
        if(activityConditionInfoMap.containsKey(activityId)){
            List<ActivityConditionInfo> cList = activityConditionInfoMap.get(activityId);
            for(ActivityConditionInfo cInfo : cList){
                if(cInfo.getConditionId() == conditionId){
                    return cInfo;
                }
            }
        }
        return null;
    }

    public static List<ActivityConditionInfo> getActivityConditionInfoByType(int activityId,int type){
        List<ActivityConditionInfo> resList = new ArrayList<>();
        if(activityConditionInfoMap.containsKey(activityId)){
            List<ActivityConditionInfo> cList = activityConditionInfoMap.get(activityId);
            for(ActivityConditionInfo cInfo : cList){
                if(cInfo.getType() == type){
                    resList.add(cInfo);
                }
            }
        }
        return resList;
    }

    public void initActivityInfo(int activtyId){
        ResultSet rs = null;
        CallableStatement call = null;
        Map<Integer, ActivityInfo> dataMap = new ConcurrentHashMap<>();
        String sql = "select * from t_s_activity_main where activityId = ?";
        try {
            getDb().setConnName(DbNameStrategy.getServerDb());
            call = getDb().getConnection().prepareCall(sql);
            call.setInt(1, activtyId);
            rs = call.executeQuery();
            while (rs.next()) {
                ActivityInfo data = parseActivityInfo(rs);
                activityInfoMap.put(data.getActivityId(), data);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            getDb().closeConnection(call, rs);
        }
    }

    public void initActivityConditionInfoMap(Integer activityId) {
        ResultSet rs = null;
        CallableStatement call = null;
        String sql = "select * from t_s_activity_condition where activityId = ? ";
        try {
            getDb().setConnName(DbNameStrategy.getServerDb());
            call = getDb().getConnection().prepareCall(sql);
            call.setInt(1,activityId);
            rs = call.executeQuery();
            while (rs.next()) {
                ActivityConditionInfo data = parseActivityConditionInfo(rs);
                if (!activityConditionInfoMap.containsKey(data.getActivityId())) {
                    activityConditionInfoMap.put(data.getActivityId(), new ArrayList<>());
                }
                activityConditionInfoMap.get(data.getActivityId()).add(data);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            getDb().closeConnection(call, rs);
        }
    }

    public Set<Integer> getConditionInfoMap(Integer activityId) {
        Set<Integer> list = new HashSet<>();
        List<ActivityConditionInfo> conditionInfoList = activityConditionInfoMap.get(activityId);
        if (conditionInfoList != null) {
            for (ActivityConditionInfo info : conditionInfoList) {
                int type = info.getType();
                list.add(type);
            }
        }
        return list;
    }

    private ActivityInfo parseActivityInfo(ResultSet rs) throws SQLException {
        ActivityInfo data = new ActivityInfo();
        data.setActivityId(rs.getInt("activityId"));
        data.setActivityName(rs.getString("activityName"));
        data.setActivityDesc(rs.getString("activityDesc"));
        data.setType(rs.getInt("type"));
        data.setChildType(rs.getInt("childType"));
        data.setBeginShowTime(rs.getTimestamp("beginShowTime").getTime() / 1000);
        data.setEndShowTime(rs.getTimestamp("endShowTime").getTime() / 1000);
        data.setBeginTime(rs.getTimestamp("beginTime").getTime() / 1000);
        data.setEndTime(rs.getTimestamp("endTime").getTime() / 1000);
        data.setIcon(rs.getString("icon"));
        data.setOrder(rs.getInt("order"));
        data.setParam1(rs.getString("param1"));
        data.setParam2(rs.getString("param2"));
        data.setParam3(rs.getString("param3"));
        data.setParam4(rs.getString("param4"));
        data.setParam5(rs.getString("param5"));
        data.setParam6(rs.getString("param6"));
        data.setUnionGroup(rs.getString("unionGroup"));
        data.setServerListStr(rs.getString("serverList"));
        data.setServerIdList(StringUtils.stringToLongList(data.getServerListStr(), ","));
        data.setServerListStr2(rs.getString("serverList2"));
        data.setCrossId(rs.getLong("crossServerId"));
        return data;
    }

    private ActivityConditionInfo parseActivityConditionInfo(ResultSet rs) throws SQLException {
        ActivityConditionInfo data = new ActivityConditionInfo();
        data.setConditionId(rs.getInt("id"));
        data.setActivityId(rs.getInt("activityId"));
        data.setTitle(rs.getString("title"));
        data.setDesc(rs.getString("desc"));
        data.setType(rs.getInt("type"));
        data.setRewardStr(rs.getString("rewards"));
        data.setParamStr(rs.getString("params"));
        data.setReward(PropertyHelper.parseStringToProperty(data.getRewardStr()));
        data.setParamList(StringUtils.stringToBigIntegerList(data.getParamStr(), "\\|"));
        String value = rs.getString("extendParam");
        if(!StringUtils.isNullOrEmpty(value)){
            data.setExtendParam(value);
        }
        //职位奖励 会长奖励|副会长奖励|精英奖励
        data.setPositionRewardStr(rs.getString("masterRewards"));
        List<String> positionStrList = StringUtils.stringToStringList(data.getPositionRewardStr(), "\\|");
        if (positionStrList.size() > 0 && !StringUtils.isNullOrEmpty(positionStrList.get(0))) {
            data.setMasterReward(PropertyHelper.parseStringToProperty(positionStrList.get(0)));
            data.setMasterRewardStr(positionStrList.get(0));
        }
        if (positionStrList.size() > 1 && !StringUtils.isNullOrEmpty(positionStrList.get(1))) {
            data.setDeputyMasterRewardStr(positionStrList.get(1));
        }
        if (positionStrList.size() > 2 && !StringUtils.isNullOrEmpty(positionStrList.get(2))) {
            data.setEliteRewardStr(positionStrList.get(2));
        }
        data.setActtype(rs.getString("acttype"));
        data.setSubText(rs.getString("subText"));
        data.setIsOneBuy(rs.getString("isOneBuy"));
        return data;
    }


    public List<Map<String, String>> getDayRechargeAc(ActivityInfo activityInfo){
        String dateStart = DateHelper.getCurrentDateTimeString(activityInfo.getBeginShowTime()*1000);
        String dateEnd = DateHelper.getCurrentDateTimeString(activityInfo.getEndShowTime()*1000);
        ResultSet rs = null;
        CallableStatement call = null;
        List<Map<String, String>> dataList = new ArrayList<>();
        String sql = "SELECT sum(price) as totalRecharge,userId,serverId,LEFT(`time`,10) as date FROM t_s_recharge_detail " +
                "WHERE `time` > ? AND `time` < ? AND serverId in(" + activityInfo.getServerListStr() + ")" +
                "GROUP BY userId,TO_DAYS(`time`)";
        try {
            getDb().setConnName(DbNameStrategy.getServerDb());
            call = getDb().getConnection().prepareCall(sql);
            call.setString(1, dateStart);
            call.setString(2, dateEnd);
            rs = call.executeQuery();
            while (rs.next()) {
                while (rs.next()) {
                    Map<String,String> temp = new ConcurrentHashMap<>();
                    temp.put("serverId",rs.getString("serverId"));
                    temp.put("userId",rs.getString("userId"));
                    temp.put("date",rs.getString("date"));
                    temp.put("totalRecharge",rs.getString("totalRecharge"));
                    dataList.add(temp);
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            getDb().closeConnection(call, rs);
        }
        return dataList;
    }
}
